package com.example.demo.dao.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.dao.RedisDao;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Slf4j
@AllArgsConstructor
public class RedisDaoImpl implements RedisDao {
    private final StringRedisTemplate stringRedisTemplate;

    @Override
    public StringRedisTemplate template() {
        return stringRedisTemplate;
    }

    /**
     * 保存缓存
     */
    public void save(String key, String hashKey, Object value, Duration duration) {
        if (stringRedisTemplate == null) {
            return;
        }
        Object content = null;
        if (value instanceof Optional) {
            Optional<?> optional = ((Optional<?>) value);
            content = optional.orElse(null);
        } else {
            content = value;
        }
        Optional.ofNullable(content)
                .map(s -> s instanceof String ? s : JSONObject.toJSONString(s))
                .map(Object::toString)
                .ifPresent(s -> {
                    if (hashKey == null) {
                        stringRedisTemplate.opsForValue().set(key, s, duration);
                    } else {
                        stringRedisTemplate.opsForHash().put(key, hashKey, s);
                        stringRedisTemplate.expire(key, duration.getSeconds(), TimeUnit.SECONDS);
                    }
                });
    }

    public Optional<String> loadString(String key, Object hashKey) {
        return Optional.ofNullable(stringRedisTemplate)
                .map(template -> hashKey == null ?
                        template.opsForValue().get(key) : template.opsForHash().get(key, hashKey))
                .map(Object::toString);
    }
}
